package goweb

import (
	"fmt"
	"log"
	"net/http"
)

const ANY = "ANY"

// 自定义一个函数类型
type HandleFunc func(ctx *Context)

// 路由分组
type routerGroup struct {
	name             string
	handlerFuncMap   map[string]map[string]HandleFunc
	handlerMethodMap map[string][]string
	treeNode         *TreeNode
}

// 定义一个路由的结构体
type router struct {
	routerGroups []*routerGroup
}

func (r *router) Group(name string) *routerGroup {
	routerGroup := &routerGroup{
		name:             name,
		handlerFuncMap:   make(map[string]map[string]HandleFunc),
		handlerMethodMap: make(map[string][]string),
		treeNode:         &TreeNode{name: "/", children: make([]*TreeNode, 0)},
	}
	r.routerGroups = append(r.routerGroups, routerGroup)
	return routerGroup

}

// 定义一个引擎结构体
type Engine struct {
	router // 继承router结构体
}

//	func (r *routerGroup) Add(name string, handleFunc HandleFunc) {
//		r.handlerFuncMap[name] = handleFunc
//	}
func (r *routerGroup) handle(name, method string, handleFunc HandleFunc) {
	_, ok := r.handlerFuncMap[name]
	if !ok {
		r.handlerFuncMap[name] = make(map[string]HandleFunc)
	}
	_, ok = r.handlerFuncMap[name][method]
	if ok {
		panic("有重复的路由")
	}
	r.handlerFuncMap[name][method] = handleFunc
	r.treeNode.Put(name)
}

func (r *routerGroup) Any(name string, handleFunc HandleFunc) {
	r.handle(name, ANY, handleFunc)

}
func (r *routerGroup) Get(name string, handleFunc HandleFunc) {
	r.handle(name, http.MethodGet, handleFunc)
}

func (r *routerGroup) Post(name string, handleFunc HandleFunc) {
	r.handle(name, http.MethodPost, handleFunc)
}

func (engine *Engine) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	methon := r.Method
	fmt.Println(methon)
	for _, group := range engine.routerGroups {
		routerName := SubStingLast(r.RequestURI, "/"+group.name)
		node := group.treeNode.Get(routerName)
		if node != nil {
			// 路由匹配上
			// 业务逻辑
			ctx := &Context{
				W: w,
				R: r,
			}
			handle, ok := group.handlerFuncMap[routerName][ANY]
			if ok {
				handle(ctx)
				return
			}
			// method进行匹配
			handle, ok = group.handlerFuncMap[routerName][methon]
			if ok {
				handle(ctx)
				return
			}
			// 路由有，请求方式没有，抛出405
			w.WriteHeader(http.StatusMethodNotAllowed)
			fmt.Fprintf(w, "%s %s not allowed \n", r.RequestURI, methon)
			return

		}
		//for name, methodHandle := range group.handlerFuncMap {
		//	url := "/" + group.name + name
		//	if r.RequestURI == url { // 路由是匹配的
		//
		//	}
		//}
	}
	w.WriteHeader(http.StatusNotFound)
	fmt.Fprintf(w, "%s not found \n", r.RequestURI)
	return
}

func New() *Engine {
	return &Engine{
		router: router{},
	}
}

func (engine *Engine) Run() {
	// user key:get value func
	//for _, group := range engine.routerGroups {
	//	for key, value := range group.handlerFuncMap {
	//		http.HandleFunc("/"+group.name+key, value)
	//	}
	//}
	http.Handle("/", engine)

	err := http.ListenAndServe(":8011", nil)
	if err != nil {
		log.Fatal(err)
	}

}
